package tetris;

/**
 * File: ControlPanel.java
 * User:���ة
 * Date: 2004.12.3
 * Describe: ����˹����� Java ʵ��
 */
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;

/**
 * ��������࣬�̳���JPanel. �ϱ߰���Ԥ�Դ��ڡ��ȼ����÷֡����ư�ť ��Ҫ����������Ϸ��̡�
 */
class ControlPane extends JPanel {
	private JTextField tfLevel = new JTextField("" + MainFrame.DEFAULT_LEVEL), tfScore = new JTextField("0");
	private JButton btPlay = new JButton("Play"), btPause = new JButton("Pause"), btStop = new JButton("Stop"), btTurnLevelUp = new JButton(
			"Turn hard"), btTurnLevelDown = new JButton("Turn easy");
	private JPanel plTip = new JPanel(new BorderLayout());
	private TipPanel plTipBlock = new TipPanel();
	private JPanel plInfo = new JPanel(new GridLayout(4, 1));
	private JPanel plButton = new JPanel(new GridLayout(5, 1));
	private Timer timer;
	private MainFrame game;
	private Border border = new EtchedBorder(EtchedBorder.RAISED, Color.white, new Color(148, 145, 140));

	/**
	 * ���������Ĺ��캯��
	 * 
	 * @param game
	 *            ErsBlocksGame, ErsBoxesGame���һ��ʵ�����ã�
	 *            ����ֱ�ӿ���ErsBoxesGame�����Ϊ��
	 */
	public ControlPane(final MainFrame game) {
		setLayout(new GridLayout(3, 1, 0, 4));
		this.game = game;
		plTip.add(new JLabel("Next block"), BorderLayout.NORTH);
		plTip.add(plTipBlock);
		plTip.setBorder(border);
		plInfo.add(new JLabel("Level"));
		plInfo.add(tfLevel);
		plInfo.add(new JLabel("Score"));
		plInfo.add(tfScore);
		plInfo.setBorder(border);
		tfLevel.setEditable(false);
		tfScore.setEditable(false);
		plButton.add(btPlay);
		plButton.add(btPause);
		plButton.add(btStop);
		plButton.add(btTurnLevelUp);
		plButton.add(btTurnLevelDown);
		plButton.setBorder(border);
		add(plTip);
		add(plInfo);
		add(plButton);
		addKeyListener(new ControlKeyListener());
		btPlay.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				game.playGame();
			}
		});
		btPause.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				if (btPause.getText().equals(new String("Pause"))) {
					game.pauseGame();
				} else {
					game.resumeGame();
				}
			}
		});
		btStop.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				game.stopGame();
			}
		});
		btTurnLevelUp.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				try {
					int level = Integer.parseInt(tfLevel.getText());
					if (level < MainFrame.MAX_LEVEL)
						tfLevel.setText("" + (level + 1));
				} catch (NumberFormatException e) {
				}
				requestFocus();
			}
		});
		btTurnLevelDown.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				try {
					int level = Integer.parseInt(tfLevel.getText());
					if (level > 1)
						tfLevel.setText("" + (level - 1));
				} catch (NumberFormatException e) {
				}
				requestFocus();
			}
		});
		addComponentListener(new ComponentAdapter() {
			public void componentResized(ComponentEvent ce) {
				plTipBlock.fanning();
			}
		});
		timer = new Timer(500, new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				tfScore.setText("" + game.getScore());
				int scoreForLevelUpdate = game.getScoreForLevelUpdate();
				if (scoreForLevelUpdate >= MainFrame.PER_LEVEL_SCORE && scoreForLevelUpdate > 0)
					game.levelUpdate();
			}
		});
		timer.start();
	}

	/**
	 * ����Ԥ�Դ��ڵ���ʽ��
	 * 
	 * @param style
	 *            int,��ӦErsBlock���STYLES�е�28��ֵ
	 */
	public void setTipStyle(int style) {
		plTipBlock.setStyle(style);
	}

	/**
	 * ȡ���û����õ���Ϸ�ȼ���
	 * 
	 * @return int, �Ѷȵȼ���1 �� ErsBlocksGame.MAX_LEVEL
	 */
	public int getLevel() {
		int level = 0;
		try {
			level = Integer.parseInt(tfLevel.getText());
		} catch (NumberFormatException e) {
		}
		return level;
	}

	/**
	 * ���û��޸���Ϸ�Ѷȵȼ���
	 * 
	 * @param level
	 *            �޸ĺ����Ϸ�Ѷȵȼ�
	 */
	public void setLevel(int level) {
		if (level > 0 && level < 11)
			tfLevel.setText("" + level);
	}

	/**
	 * ����"��ʼ"��ť��״̬��
	 */
	public void setPlayButtonEnable(boolean enable) {
		btPlay.setEnabled(enable);
	}

	public void setPauseButtonLabel(boolean pause) {
		btPause.setText(pause ? "Pause" : "Continue");
	}

	/**
	 * ���ÿ������
	 */
	public void reset() {
		tfScore.setText("0");
		plTipBlock.setStyle(0);
	}

	/**
	 * ���¼���TipPanel���boxes[][]���С��Ĵ�С
	 */
	public void fanning() {
		plTipBlock.fanning();
	}

	/**
	 * Ԥ�Դ��ڵ�ʵ��ϸ����
	 */
	private class TipPanel extends JPanel {
		private Color backColor = Color.darkGray, frontColor = Color.lightGray;
		private TetrisCell[][] boxes = new TetrisCell[TetrisShape.BOXES_ROWS][TetrisShape.BOXES_COLS];
		private int style, boxWidth, boxHeight;
		private boolean isTiled = false;

		/**
		 * Ԥ�Դ����๹�캯��
		 */
		public TipPanel() {
			for (int i = 0; i < boxes.length; i++) {
				for (int j = 0; j < boxes[i].length; j++)
					boxes[i][j] = new TetrisCell(false);
			}
		}

		/**
		 * Ԥ�Դ����๹�캯��
		 * 
		 * @param backColor
		 *            Color, ���ڵı���ɫ
		 * @param frontColor
		 *            Color, ���ڵ�ǰ��ɫ
		 */
		public TipPanel(Color backColor, Color frontColor) {
			this();
			this.backColor = backColor;
			this.frontColor = frontColor;
		}

		/**
		 * ����Ԥ�Դ��ڵķ�����ʽ
		 * 
		 * @param style
		 *            int,��ӦErsBlock���STYLES�е�28��ֵ
		 */
		public void setStyle(int style) {
			this.style = style;
			repaint();
		}

		/**
		 * ����JComponent��ĺ��������
		 * 
		 * @param g
		 *            ͼ���豸����
		 */
		public void paintComponent(Graphics g) {
			super.paintComponent(g);
			if (!isTiled)
				fanning();
			int key = 0x8000;
			for (int i = 0; i < boxes.length; i++) {
				for (int j = 0; j < boxes[i].length; j++) {
					Color color = (((key & style) != 0) ? frontColor : backColor);
					g.setColor(color);
					g.fill3DRect(j * boxWidth, i * boxHeight, boxWidth, boxHeight, true);
					key >>= 1;
				}
			}
		}

		/**
		 * ��ݴ��ڵĴ�С���Զ������ĳߴ�
		 */
		public void fanning() {
			boxWidth = getSize().width / TetrisShape.BOXES_COLS;
			boxHeight = getSize().height / TetrisShape.BOXES_ROWS;
			isTiled = true;
		}
	}

	private class ControlKeyListener extends KeyAdapter {
		public void keyPressed(KeyEvent ke) {
			if (!game.isPlaying())
				return;
			TetrisShape block = game.getCurBlock();
			switch (ke.getKeyCode()) {
			case KeyEvent.VK_DOWN:
				block.moveDown();
				break;
			case KeyEvent.VK_LEFT:
				block.moveLeft();
				break;
			case KeyEvent.VK_RIGHT:
				block.moveRight();
				break;
			case KeyEvent.VK_UP:
				block.turnNext();
				break;
			default:
				break;
			}
		}
	}
}
